package io.zerous.engine.math

/**
 * Created by Zerous on 2018/2/15.
 */
class Vector2 {
    var x: Float
    var y: Float

    constructor(x: Float, y: Float) {
        this.x = x
        this.y = y
    }

    constructor() {
        x = 0f
        y = 0f
    }

    constructor(other: Vector2) {
        x = other.x
        y = other.y
    }

    fun set(x: Float, y: Float): Vector2 {
        this.x = x
        this.y = y
        return this
    }

    fun set(other: Vector2): Vector2 {
        this.x = other.x
        this.y = other.y
        return this
    }

    fun len() = Math.sqrt((x * x + y * y).toDouble()).toFloat()
    fun squaredLen() = square(x) + square(y)

    fun squaredDistance(px: Float, py: Float) = square(x - px) + square(y - py)
    fun squaredDistance(other: Vector2) = squaredDistance(other.x, other.y)

    fun distance(px: Float, py: Float) = Math.sqrt(squaredDistance(px, py).toDouble()).toFloat()
    fun distance(other: Vector2) = distance(other.x, other.y)

    fun rotate(rad: Double) {
        x = Math.cos(rad).toFloat() * x - Math.sin(rad).toFloat() * y
        y = Math.sin(rad).toFloat() * x + Math.cos(rad).toFloat() * y
    }

    fun normalize() = Vector2(this / this.len())

    fun cosWith(other: Vector2) = Math.acos((this * other/len() * other.len()).toDouble())

    fun copy() = Vector2(this)

    override fun equals(other: Any?): Boolean {
        return if (other is Vector2) {
            x == other.x && y == other.y
        } else {
            false
        }
    }

    operator fun plus(other: Vector2) = Vector2(x + other.x, y + other.y)

    operator fun plusAssign(other: Vector2) {
        x += other.x
        y += other.y
    }

    operator fun minus(other: Vector2) = Vector2(x - other.x, y - other.y)

    operator fun times(scalar: Float) : Vector2 = Vector2(x * scalar, y * scalar)

    operator fun div(scalar: Float) : Vector2 = Vector2(x / scalar, y / scalar)

    operator fun times(other: Vector2): Float = x * other.x + y * other.y

    override fun hashCode(): Int = super.hashCode()

    override fun toString() = "[$x, $y]"
}